package com.lld.im.tcp.handler;

import com.lld.im.tcp.utils.SessionSocketHolder;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.lld.im.common.constant.Constants;

/**
 * @author: LunBoWang
 * @description: 心跳检测处理器
 * @date: 2025/3/27 下午7:21
 * @version: 1.0
 */
@Slf4j
public class HeartBeatHandler extends ChannelInboundHandlerAdapter {

    private Long heartBeatTime;

    public HeartBeatHandler(Long heartBeatTime) {
        this.heartBeatTime = heartBeatTime;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

        //判断evt是否是IdleStateEvent（用于触发用户事件，包含读空闲、写空闲和读写空闲）
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent) evt;
            if(event.state()== IdleState.READER_IDLE){
                //读空闲
                log.info("读空闲");
            } else if (event.state()==IdleState.WRITER_IDLE) {
                log.info("写空闲");
            } else if (event.state()==IdleState.ALL_IDLE) {
                // 获取当前channel上一次读写操的时间
                Long lastReadTime = (Long)ctx.channel().attr(AttributeKey.valueOf(Constants.readTime)).get();
                // 获取当前时间
                long now = System.currentTimeMillis();
                // 如果现在时间距离上次读写时间超过了心跳时间
                if(lastReadTime!=null&&now-lastReadTime>heartBeatTime){
                    // 退出后台逻辑
                    SessionSocketHolder.offlineUserSession((NioSocketChannel) ctx.channel());
                }
            }
        }
    }
}
